    //The renderInfo() method is required in every gadget.js compiled by this project's ant script.
    //It will receive all callbacks. Sorry if this is to simplistic for you needs;
    //I'm sure we can think of something more flexible in due time.
    
    //Display a table that allows every participant to choose
    //  - whether they're coming for a Friday after-work beer
    //  - when they expect to arrive at Oersted (or whereever)
    function renderInfo() {
      if (!wave.getState()) {
        return;
      }
      var state = wave.getState();
      var participants = wave.getParticipants();
      //In this example we'll be writing an entire HTML table into an innerHTML field
      var tableHTML = "";
      for (var i = 0; i < participants.length; ++i) {
          //The table will have one row for each participant (yeah, bots get to have a say too)
          var person = participants[i];
          tableHTML += "<tr>";
          //Who is it?
          tableHTML += "<td><img src ='" + person.getThumbnailUrl() + "' height='50' width='50'/></td>";
          tableHTML += "<td>" + person.getDisplayName() + "</td>";
          var id = person.getId();
          //Dropdown with all possible choices
          tableHTML += "<td align='center'>" + choiceHTML(id, state) + "</td>";
          tableHTML += "</tr>";
      }
      //NOTE: It's important that some tag in gadget.html has id='all' to match this:
      document.getElementById('all').innerHTML = tableHTML;
      //Resize gadget height to fit the actual content
      gadgets.window.adjustHeight();
    }

    //Return HTML for a dropdown box with a number of choices
    //This is the only method that reads gadget state
    function choiceHTML(id, state) {
      //There's one key for every participant id. The key is just the id.
      var key = id;
      //Look up the value. If the participant hasn't made a choice, default to "unset".
      var current = state.get(key);
      if (!current) {
        current = "unset";
      }
      //Dropdown box that calls setState() below when updated.
      var result = "<select name='" + key + "' onchange='setState(this.name,this.value)'>";
      result += "<option " + attrs("unset", current, id) + ">is hesitating</option>";
      result += "<option " + attrs("none", current, id) + ">no beer</option>";
      result += "<option " + attrs("16", current, id) + ">be there 16-ish</option>";
      result += "<option " + attrs("17", current, id) + ">be there 17-ish</option>";
      result += "<option " + attrs("18", current, id) + ">...later</option>";
      result += "<option " + attrs("19", current, id) + ">...it's complicated</option>";
      result += "</select>";
      return result;
    }

    //Outputs HTML for one choice.
    //Makes this choice the displayed (i.e. "selected") one if it matches the value for the participant's id.
    //The choice is disabled if the participant is not the viewer (so no choices are available for anyone else).
    function attrs(value, currentChoice, id) {
    	return "value='" + value + "'" + ((value == currentChoice) ? "selected='selected'" : "") + ((id == wave.getViewer().getId()) ? "'" : "disabled='disabled'");
    }

    //This method is called when a dropdown value is changed.
    //It saves the choice in the gadget state.
    //As we don't allow the viewer to make choices for anyone but herself, 
    //key is expected to be the viewer's id, but it is not checked.
    function setState(key, value) {
      delta = {};
      delta["" + key] = "" + value;
      logThis(delta);
      wave.getState().submitDelta(delta);
    }
